from django.shortcuts import render,redirect
#导包
from django.http import HttpResponse,HttpResponseRedirect,JsonResponse
#导入类视图
from django.views import View

import json
from django.core.serializers import serialize
from rest_framework.response import Response
from rest_framework.views import APIView
#导入加密库
import hashlib
#导入图片库
#绘画库
from PIL import ImageDraw
#字体库
from PIL import ImageFont
#图片库
from PIL import Image
#随机库
import random
#文件流
import io

import requests

#导入上传文件夹配置
from mydjango.settings import UPLOAD_ROOT
import os

#导入原生sql模块
from django.db import connection

import jwt

#导入redis数据库
import redis

#导入时间模块
import time

import hmac
import base64
from hashlib import sha256
import urllib

#导入公共目录变量
from mydjango.settings import BASE_DIR

#导包
from django.db.models import Q,F

#导入dwebsocket的库
from dwebsocket.decorators import accept_websocket
import uuid

from myapp.models import User,Cate,Pics,Goods,Comment,UserFlow
from myapp.myser import CateSer,UserSer,PicsSer,GoodsSer,CommentSer


#定义ip地址和端口
host = "127.0.0.1"
port = 6379

#链接对象
r = redis.Redis(host=host,port=port)

import pymongo

#建立mongo的链接对象
mongo_client = pymongo.MongoClient(host='localhost',port=27017)

#导入bson
from bson import json_util as jsonb


#商品检索接口
class GoodsSearch(APIView):

	def get(self,request):


		#接收参数
		word = request.GET.get("word",None)

		#检索  模糊匹配 管道 代表 or 并且 &
		#翻译sql select * from goods where (name like '%word%' or desc like '%word%') and (parms like '%word%')
		goodslist = Goods.objects.filter(Q(name__icontains=word) | Q(desc__icontains=word) )

		#序列化
		goods_ser = GoodsSer(goodslist,many=True)

		return Response(goods_ser.data)




#工具方法，获取前n名的数据
def get_top_n(num):

	#获取redis数据
	goods_click = r.zrange('good_rank',0,-1,desc=True,withscores=True)[:num]
	#获取mysql数据
	goods = Goods.objects.in_bulk([int(item[0]) for item in goods_click])

	#合并操作
	res = []
	for item in goods_click:

		#遍历列表
		#捕获异常，防止mysql和redis数据不同步问题
		try:
			res.append({int(item[1]):goods[int(item[0])]})
		except Exception as e:
			pass

	print(res)

	return res


#商品排行榜数据视图
class GoodRank(APIView):

	def get(self,request):

		#获取排名前n的数据
		get_res = get_top_n(10)

		res = []
		#遍历进行序列化
		for dic in get_res:
			for k,v in dic.items():
				#序列化
				data = GoodsSer(v).data
				#将商品点击数附加到商品序列化数据中
				data['clicks'] = k
				res.append(data)

		#返回
		return Response(res)


#新的商品参与排名
class GoodsClick(APIView):

	def get(self,request):

		#接收参数
		id = request.GET.get("id",None)

		#修改商品的点击数
		r.zincrby("good_rank",1,int(id))

		get_top_n(10)

		return Response({"message":"访问加1"})




#对结果集美化方法
def dictfetchall(cursor):

	#获取游标描述
	desc = cursor.description

	return [

	dict(zip( [col[0] for col in desc ] ,row))

	for row in cursor.fetchall()


	]

#商品关注接口(查询用户关注过的商品列表)
class UidFlow(View):

	def get(self,request):

		uid = request.GET.get("uid",None)

		#建立游标对象
		cursor = connection.cursor()

		#执行sql语句
		cursor.execute('select a.id,a.name,a.create_time from goods a left join userflow b on a.id = b.gid where b.uid = %s ' % str(uid))

		#获取结果
		#result = cursor.fetchall()
		result = dictfetchall(cursor)

		#返回结果 手动序列化
		return HttpResponse(json.dumps(result,ensure_ascii=False,indent=4,default=str),content_type='application/json')


#关注商品接口(取关)
class GetFlow(APIView):

	def get(self,request):

		id = request.GET.get("id",None)
		uid = request.GET.get("uid",None)
		type = request.GET.get("type",1)

		if int(type) == 1:

			#关注
			userflow = UserFlow(gid=int(id),uid=int(uid))
			try:
				userflow.save()
				message = "关注成功"
				goods = Goods.objects.filter(id=int(id)).first()
				goods.flow = goods.flow + 1
				goods.save()
			except Exception as e:
				print(str(e))
				message = "不能重复关注"
				pass
			
		elif int(type) == 0:
			#取关
			UserFlow.objects.filter(gid=int(id),uid=int(uid)).delete()
			message = "取关成功"
			goods = Goods.objects.filter(id=int(id)).first()
			goods.flow = goods.flow - 1
			goods.save()

		else:
			#批量取关
			ids = request.GET.get("ids",None)
			#批量操作  gid__in([2,4,5,6,])
			UserFlow.objects.filter(uid=int(uid)).delete()
			#强转
			id_list = eval(ids)

			for id in id_list:
				userflow = UserFlow(gid=int(id),uid=int(uid))
				userflow.save()

			message = "批量关注成功"




		return Response({'message':message})





#用户列表
class UserList(APIView):

	def get(self,request):

		#查询
		user = User.objects.filter()
		#序列化
		user_ser = UserSer(user,many=True)

		return Response(user_ser.data)


#评论列表
class CommentList(APIView):

	def get(self,request):

		#商品id
		id = request.GET.get("id",None)

		#查询评论
		comment = Comment.objects.filter(gid=int(id)).order_by("-id")

		#序列化
		comment_ser = CommentSer(comment,many=True)

		return Response(comment_ser.data)

#反序列化入库(商品评论)
class InsertComment(APIView):

	def post(self,request):


		print(request.data)

		uid = request.POST.get("uid",None)

		print(uid)

		#data = request.data.copy()
		#data['create_time'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

		if r.get(str(uid)):

			return Response({'code':403,'message':'您评论的太快了，请歇一歇'})

		#初始化参数
		comment = CommentSer(data=request.data)
		#数据校验
		if comment.is_valid():
			#数据入库
			#comment.create(comment.data)
			comment.save()

			#插入评论标记
			r.set(str(uid),"123")
			r.expire(str(uid),30)

		return Response({'code':200,'message':'恭喜，评论成功'})




#统计在线人数
class GetOnLine(APIView):

	def get(self,request):

		#获取客户ip
		if 'HTTP_X_FORWARDED_FOR' in request.META:

			ip = request.META.get('HTTP_X_FORWARDED_FOR')

		else:

			ip = request.META.get('REMOTE_ADDR')

		#对用户ip进行存储
		r.sadd("online",ip)

		#设置超时时间 超时时常单位秒
		r.expire("online",20)

		#获取在线人数的数量
		myset = r.smembers('online')

		#返回数据
		return Response({'online':len(myset)})





#获取商品标签接口
class GetTags(View):

	def get(self,request):

		id = request.GET.get("id",None)

		#建立数据库对象
		db = mongo_client.md
		#建立表对象
		table = db.mytag

		#查询数据
		res = table.find_one({"gid":str(id)})

		return HttpResponse(jsonb.dumps(res,ensure_ascii=False))




#商品标签添加接口
class InsertTags(APIView):

	def get(self,request):

		id = request.GET.get("id",None)
		tags = request.GET.get("tags",None)
		tags = tags.split(",")

		#建立数据库对象
		db = mongo_client.md
		#建立表对象
		table = db.mytag

		#排重操作
		#查询
		res = table.find({"gid":str(id)}).count()

		if res > 0:
			return Response({'message':'重复数据'})

		else:
			#入库操作
			table.insert({"gid":str(id),"tags":tags})

			return Response({'message':'入库成功'})


#商品信息接口
class GoodInfo(APIView):

	def get(self,request):

		id = int(request.GET.get("id",0))

		#查询数据
		good = Goods.objects.get(id=id)

		#序列化操作
		good_ser = GoodsSer(good)

		return Response(good_ser.data)




#商品列表页
class GoodsList(APIView):

	def get(self,request):
		#当前页
		page = int(request.GET.get("page",1))
		#一页有多少条商品
		size = int(request.GET.get("size",1))

		#定义从哪儿开始切
		data_start = (page-1) * size

		#定义切到哪儿
		data_end = page * size

		#查询数据
		goodslist = Goods.objects.all()[data_start:data_end]

		#查询总数量
		count = Goods.objects.count()

		#序列化操作
		goods_ser = GoodsSer(goodslist,many=True)

		res = {}
		res['total'] = count
		res['data'] = goods_ser.data
		return Response(res)



#更新商品
class UpdateGoods(APIView):

	def get(self,request):

		#接收参数  dict['username']
		name = request.GET.get('name','null')
		desc = request.GET.get('desc','null')
		parms = request.GET.get('parms','null')
		cate_id = request.GET.get('cate_id','null')
		price = request.GET.get('price','null')
		id = request.GET.get('id','null')


		#查询
		goods = Goods.objects.filter(id=int(id)).first()


		#修改属性
		goods.name=name
		goods.desc=desc
		goods.cate_id=int(cate_id)
		goods.parms=parms
		goods.price=int(price)
		goods.save()

		res = {}
		res['code'] = 200
		res['id'] = goods.id
		res['message'] = '恭喜，修改成功'

		return Response(res)


#插入幻灯片
class InsertGoods(APIView):

	def get(self,request):

		#接收参数  dict['username']
		name = request.GET.get('name','null')
		desc = request.GET.get('desc','null')
		parms = request.GET.get('parms','null')
		cate_id = request.GET.get('cate_id','null')
		price = request.GET.get('price','null')


		#排重
		goods = Goods.objects.filter(name=name).first()

		if goods:
			res = {}
			res['code'] = 405
			res['message'] = '该商品已存在'
			return Response(res)

		#入库
		goods = Goods(name=name,desc=desc,cate_id=cate_id,parms=parms,price=price)
		goods.save()

		#查询商品id
		goods = Goods.objects.filter(name=name).first()

		res = {}
		res['code'] = 200
		res['id'] = goods.id
		res['message'] = '恭喜，添加成功'

		return Response(res)
